home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
System Booster
/
System Booster.iso
/
Commodities
/
ScreenSelect
/
StickySelect
/
StickySelect.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-26
|
11KB
|
462 lines
/** ** *** MakeRev Header *** **
**
** ** StickySelect - Selector for ScreenSelect. **
**
** Copyright © 1993,1994 Markus Aalto
**
** Creation date: 27-Jul-93
**
** ------------------------------------------------------------------
** $Filename: StickySelect.c $
** $Revision: 1.1 $
** $Date: 22-Jan-94 $
**
** $Author: Markus_Aalto $
** $Comment: Freely Distributable. Use to create your own interfaces. $
**
*/
#include "StickySelect.h"
extern UBYTE version[] = "$VER: StickySelect 1.1 (30-Jan-94)";
void CleanUp( void );
void ProcessSignals( void );
void RemoveSemaphoreHook( void );
BOOL InstallSemaphoreHook( void );
BOOL OpenInterface( void );
BOOL UpdateList( void );
void SignalScreenSelect( ULONG code );
BOOL ReadParameters( void );
extern struct IntuitionBase *IntuitionBase;
extern struct GfxBase *GfxBase;
extern struct Library *GadToolsBase;
extern struct Library *UtilitiesBase;
struct List screenname_list;
struct Window *sticky_window = NULL;
struct Gadget *listview;
struct Gadget *gadg_context = NULL;
LONG update_signal = -1;
SignalUpdateNode *update_node = NULL;
LONG TopX = 0, TopY = 0;
LONG Width = 150, Height = 100;
char *pubscreen_name = NULL;
APTR vi = NULL;
struct TextAttr my_font;
ULONG ARGS[ARG_COUNT] = { NULL, NULL, NULL, NULL, NULL };
int main( int argc, char **argv )
{
NewList(&screenname_list);
if( ReadParameters() ) {
if( InstallSemaphoreHook() ) {
if( UpdateList() ) {
ProcessSignals();
}
RemoveSemaphoreHook();
}
}
CleanUp();
return(0);
}
/* Clean up most of the allocated stuff. */
void CleanUp()
{
struct Node *screennode;
if( sticky_window ) CloseWindow( sticky_window );
if( gadg_context ) FreeGadgets(gadg_context);
if( vi ) FreeVisualInfo( vi );
if( pubscreen_name ) FreeVec((void *)pubscreen_name);
if( update_node ) FreeVec((void *)update_node);
if( update_signal != -1 ) FreeSignal( update_signal );
while( screennode = RemHead(&screenname_list) ) {
if( screennode->ln_Name ) FreeVec((void *)screennode->ln_Name);
FreeVec((void *)screennode);
}
}
/* Install a SignalUpdateNode to TaskList in "ScreenSelect" public semaphore.
** And infrom ScreenSelect about it. */
BOOL InstallSemaphoreHook()
{
BOOL retval = FALSE;
UpdateDataSemaphore *uds;
update_signal = AllocSignal(-1);
if( update_signal != -1 ) {
update_node = (SignalUpdateNode *)AllocVec(sizeof(SignalUpdateNode),
MEMF_PUBLIC|MEMF_CLEAR);
if( update_node ) {
update_node->su_Task = FindTask(NULL);
update_node->su_Signal = update_signal;
Forbid();
if( uds = (UpdateDataSemaphore *)FindSemaphore(SEMAPHORE_NAME) ) {
ObtainSemaphore( (struct SignalSemaphore *)uds );
Permit();
AddTail(&uds->ud_TaskList, update_node);
if( uds->ud_ScreenSelectTask ) {
/* Notify about new client. */
uds->ud_code = CODE_NEWCLIENT;
Signal(uds->ud_ScreenSelectTask,
1 << uds->ud_ScreenSelectSignal);
}
ReleaseSemaphore( (struct SignalSemaphore *)uds );
retval = TRUE;
}
else Permit();
}
}
return(retval);
}
/* Release the SignalUpdateNode from the ScreenSelect sempahore. */
void RemoveSemaphoreHook()
{
UpdateDataSemaphore *uds;
Forbid();
if( uds = (UpdateDataSemaphore *)FindSemaphore(SEMAPHORE_NAME) ) {
ObtainSemaphore( (struct SignalSemaphore *)uds );
Permit();
Remove(update_node);
ReleaseSemaphore( (struct SignalSemaphore *)uds );
}
else Permit();
}
void ProcessSignals()
{
ULONG signal, signalmask, stickymask;
BOOL END;
ULONG class;
UWORD code;
ULONG old_secs = 0, old_mics = 0;
struct IntuiMessage *imsg;
END = OpenInterface();
while( !END ) {
stickymask = (1 << sticky_window->UserPort->mp_SigBit);
signalmask = (1 << update_signal) | SIGBREAKF_CTRL_C | stickymask;
signal = Wait( signalmask );
if( signal & SIGBREAKF_CTRL_C ) {
END = TRUE;
}
else if( signal & (1 << update_signal) ) {
GT_SetGadgetAttrs(listview, sticky_window, NULL,
GTLV_Labels, ~0,
TAG_END);
END = !UpdateList();
GT_SetGadgetAttrs(listview, sticky_window, NULL,
GTLV_Labels, &screenname_list,
TAG_END);
}
else if( signal & stickymask ) {
while( (!END) && (imsg = GT_GetIMsg(sticky_window->UserPort)) ) {
class = imsg->Class;
code = imsg->Code;
switch(class)
{
case IDCMP_CLOSEWINDOW:
END = TRUE;
break;
case IDCMP_REFRESHWINDOW:
GT_BeginRefresh(sticky_window);
GT_EndRefresh(sticky_window,TRUE);
break;
case IDCMP_GADGETUP:
if( DoubleClick( old_secs, old_mics, imsg->Seconds,
imsg->Micros) ) {
SignalScreenSelect(code);
}
old_secs = imsg->Seconds;
old_mics = imsg->Micros;
break;
}
GT_ReplyIMsg(imsg);
}
}
}
}
BOOL OpenInterface()
{
BOOL END = TRUE;
struct Screen *pub_screen;
struct NewGadget ng;
struct Gadget *gad;
struct DrawInfo *dri;
if( pub_screen = LockPubScreen(pubscreen_name) ) {
dri = GetScreenDrawInfo(pub_screen);
if( dri ) {
sticky_window = OpenWindowTags(NULL,
WA_Left, TopX,
WA_Top, TopY,
WA_Width, Width,
WA_Height, Height,
WA_IDCMP, MY_IDCMP_FLAGS,
WA_Title, "StickySelect",
WA_ScreenTitle, "StickySelect 1.1 © (1993) by Markus Aalto",
WA_PubScreen, pub_screen,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_SimpleRefresh, TRUE,
WA_AutoAdjust, TRUE,
WA_NewLookMenus, TRUE,
TAG_END);
if( sticky_window ) {
vi = GetVisualInfo( pub_screen, TAG_END);
if( vi ) {
SetFont(sticky_window->RPort, dri->dri_Font);
AskFont(sticky_window->RPort, &my_font);
gad = CreateContext(&gadg_context);
ng.ng_LeftEdge = INTERWIDTH + sticky_window->BorderLeft;
ng.ng_TopEdge = INTERHEIGHT + sticky_window->BorderTop;
ng.ng_Width = sticky_window->Width - (2*INTERWIDTH
+ sticky_window->BorderLeft + sticky_window->BorderRight);
ng.ng_Height = sticky_window->Height - (2*INTERHEIGHT
+ sticky_window->BorderTop + sticky_window->BorderBottom);
ng.ng_GadgetText = NULL;
ng.ng_TextAttr = &my_font;
ng.ng_Flags = NG_HIGHLABEL;
ng.ng_GadgetID = 0;
ng.ng_UserData = NULL;
ng.ng_VisualInfo = vi;
listview = gad = CreateGadget(LISTVIEW_KIND, gad, &ng,
GTLV_Labels, &screenname_list,
GTLV_ShowSelected, NULL,
GTLV_Selected, 0,
TAG_END);
if( gad == NULL ) {
FreeGadgets(gadg_context);
}
else {
END = FALSE;
AddGList(sticky_window, gadg_context, -1, -1, NULL);
RefreshGList(gadg_context, sticky_window, NULL, -1);
GT_RefreshWindow(sticky_window,NULL);
}
}
}
FreeScreenDrawInfo(pub_screen, dri);
}
UnlockPubScreen(NULL,pub_screen);
}
return(END);
}
/* Recreate the ScreenList for StickySelect. */
BOOL UpdateList()
{
struct Node *screennode;
struct Node *namenode;
UpdateDataSemaphore *uds;
BOOL fine = TRUE;
while( screennode = RemHead(&screenname_list) ) {
if( screennode->ln_Name ) FreeVec((void *)screennode->ln_Name);
FreeVec((void *)screennode);
}
Forbid();
if( uds = (UpdateDataSemaphore *)FindSemaphore(SEMAPHORE_NAME) ) {
ObtainSemaphoreShared( (struct SignalSemaphore *)uds );
Permit();
for(namenode = uds->ud_NameList.lh_Head; (namenode->ln_Succ) && fine;
namenode = namenode->ln_Succ) {
screennode = (struct Node *)AllocVec(sizeof(struct Node),
MEMF_ANY|MEMF_CLEAR);
if( screennode ) {
screennode->ln_Name = (UBYTE *)AllocVec(
1 + strlen(namenode->ln_Name), MEMF_ANY);
if( screennode->ln_Name ) {
strcpy( screennode->ln_Name, namenode->ln_Name );
AddTail(&screenname_list,screennode);
}
else {
fine = FALSE;
FreeVec((void *)screennode);
}
}
else fine = FALSE;
}
ReleaseSemaphore( (struct SignalSemaphore *)uds );
}
else Permit();
return(fine);
}
/* Signal ScreenSelect that User have selected new item. */
void SignalScreenSelect( ULONG code )
{
UpdateDataSemaphore *uds;
Forbid();
if( uds = (UpdateDataSemaphore *)FindSemaphore(SEMAPHORE_NAME) ) {
ObtainSemaphore( (struct SignalSemaphore *)uds );
Permit();
/* Check if semaphore is active. This means that ScreenSelect
** is around and waiting. */
if( uds->ud_ScreenSelectTask ) {
/* Notify about new selection. */
uds->ud_code = code;
Signal(uds->ud_ScreenSelectTask, 1 << uds->ud_ScreenSelectSignal);
}
ReleaseSemaphore( (struct SignalSemaphore *)uds );
}
else Permit();
}
BOOL ReadParameters()
{
UBYTE *TTString;
BOOL retval = TRUE;
if( Cli() == NULL ) {
extern struct WBStartup *_WBenchMsg;
struct WBStartup *wb_msg;
struct WBArg *wb_arg;
BPTR old_dir;
struct DiskObject *disk_obj;
char **tools;
wb_msg = _WBenchMsg;
wb_arg = wb_msg->sm_ArgList;
if(wb_arg->wa_Lock) {
old_dir = CurrentDir(wb_arg->wa_Lock);
disk_obj = GetDiskObjectNew(wb_arg->wa_Name);
if( disk_obj ) {
tools = (char **)disk_obj->do_ToolTypes;
TTString = FindToolType(tools,"PUBSCREEN");
if( TTString ) {
pubscreen_name = AllocVec(1+ strlen(TTString),
MEMF_ANY);
if( pubscreen_name ) {
strcpy(pubscreen_name,TTString);
}
else retval = FALSE;
}
TTString = FindToolType(tools,"LEFT");
if( TTString ) {
StrToLong(TTString,&TopX);
}
TTString = FindToolType(tools,"TOP");
if( TTString ) {
StrToLong(TTString,&TopY);
}
TTString = FindToolType(tools,"WIDTH");
if( TTString ) {
if( StrToLong(TTString,&Width) == -1 ) Width = 150;
}
TTString = FindToolType(tools,"HEIGHT");
if( TTString ) {
if( StrToLong(TTString,&Height) == -1 ) Height = 100;
}
FreeDiskObject(disk_obj);
}
(void)CurrentDir(old_dir);
}
}
else {
struct RDArgs *my_rda;
my_rda = ReadArgs(TEMPLATE,(LONG *)ARGS,NULL);
if( my_rda ) {
if(ARGS[ARG_PUBSCREEN] != 0) {
TTString = (char *)ARGS[ARG_PUBSCREEN];
pubscreen_name = (char *)AllocVec(1+strlen(TTString),MEMF_ANY);
if(pubscreen_name) {
strcpy(pubscreen_name,TTString);
}
else retval = FALSE;
}
if(ARGS[ARG_LEFT] != 0) {
TopX = *(ULONG *)ARGS[ARG_LEFT];
}
if(ARGS[ARG_TOP] != 0) {
TopY = *(ULONG *)ARGS[ARG_TOP];
}
if(ARGS[ARG_WIDTH] != 0) {
Width = *(ULONG *)ARGS[ARG_WIDTH];
}
if(ARGS[ARG_HEIGHT] != 0) {
Height = *(ULONG *)ARGS[ARG_HEIGHT];
}
FreeArgs(my_rda);
}
}
return(retval);
}